package team.seekers.table.utils;

import com.gargoylesoftware.htmlunit.*;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.util.NameValuePair;
import com.gargoylesoftware.htmlunit.util.UrlUtils;
import okhttp3.*;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * date: 2021/4/21 0:16
 *
 * @author GH
 * QQ 1124813753
 */
@Component
public class HttpUtil {

    private static OkHttpClient okHttpClient = new OkHttpClient().newBuilder().build();

    private static WebClient webClient = new WebClient(BrowserVersion.CHROME);

    public static Response get(String url, Map<String, String> headers) {
        Request.Builder builder = new Request.Builder().url(url);
        return getResponse(headers, builder);
    }

    public static Response post(String url, Map<String, String> headers, Map<String, String> data) {
        // 封装为表单提交
        MultipartBody.Builder dataBuilder = new MultipartBody.Builder().setType(MultipartBody.FORM);
        for (Map.Entry<String, String> entry : data.entrySet()) {
            dataBuilder.addFormDataPart(entry.getKey(), entry.getValue());
        }

        Request.Builder builder = new Request.Builder()
                .url(url)
                .post(dataBuilder.build());

        return getResponse(headers, builder);
    }

    /**
     * 根据Response获取响应体
     */
    public static String getContent(Response response) {
        String content = null;
        try {
            content = response.body().string();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return content;
    }

    /**
     * post请求获取Html格式的XML字符串
     */
    public static String getHtml(String url, Map<String, String> headers, Map<String, String> data) {
        webClient.getOptions().setUseInsecureSSL(true);
        // JS执行出错不抛出异常
        webClient.getOptions().setThrowExceptionOnScriptError(false);
        // Http状态为非200不抛出异常
        webClient.getOptions().setThrowExceptionOnFailingStatusCode(false);
        webClient.getOptions().setActiveXNative(false);
        // 不需要启用CSS
        webClient.getOptions().setCssEnabled(false);
        // 需要JS渲染后的结果
        webClient.getOptions().setJavaScriptEnabled(true);
        // 支持Ajax
        webClient.setAjaxController(new NicelyResynchronizingAjaxController());
        webClient.getOptions().setTimeout(10000);
        webClient.setJavaScriptTimeout(30000);

        String res = null;
        try {
            WebRequest request = new WebRequest(UrlUtils.toUrlSafe(url), HttpMethod.GET);
            if (data != null) {
                List<NameValuePair> params = new ArrayList<>();
                for (Map.Entry<String, String> entry : data.entrySet()) {
                    params.add(new NameValuePair(entry.getKey(), entry.getValue()));
                }
                request.setRequestParameters(params);
            }

            request.setAdditionalHeader("Host", "jw.v.zzu.edu.cn");
            request.setAdditionalHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.128 Safari/537.36 Edg/89.0.774.77");
            if (headers != null) {
                for (Map.Entry<String, String> entry : headers.entrySet()) {
                    request.setAdditionalHeader(entry.getKey(), entry.getValue());
                }
            }

            HtmlPage htmlPage = webClient.getPage(request);
            // 等待JS渲染
            webClient.waitForBackgroundJavaScript(2000);
            res = htmlPage.asXml();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return res;
    }

    public static void closeClient() {
        webClient.close();
    }

    private static Response getResponse(Map<String, String> headers, Request.Builder builder) {
        builder.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.128 Safari/537.36 Edg/89.0.774.77");
        builder.addHeader("Host", "jw.v.zzu.edu.cn");

        if (headers != null) {
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                builder.addHeader(entry.getKey(), entry.getValue());
            }
        }

        Call call = okHttpClient.newCall(builder.build());
        Response response = null;
        try {
            response = call.execute();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return response;
    }
}
